class Compiler{
    constructor(vm){
        this.el=vm.$el;
        this.vm=vm;
        this.compile(this.el)
    }
    compile(el){
        //编译模板处理文本节点和元素节点
        let childNodes=el.childNodes;
        Array.from(childNodes).forEach(node=>{
            if(this.isTextNode(node)){
                //处理文本节点
                this.compileText(node)
            }else if(this.isElementNode(node)){
                //处理元素节点
                this.compileElement(node)
            }
            //判断 node 是否还有子节点  有的话 递归调用compile
            if(node.childNodes && node.childNodes.length !==0){
                this.compile(node)
            }
        })

    }
    compileElement(node){
      //编译元素节点处理指令
      //遍历所有属性节点
        Array.from(node.attributes).forEach(attr=>{
            let attrName=attr.name
            //判断是否是指令
            if(this.isDirective(attrName)){
                attrName=attrName.substr(2)
                //v-text 截取成 text   v-model 截取成 model v-on
                
                if(attrName.startsWith("on")){
                    attrName=attrName.split(":")
                    this.bindlistnner(node,attrName[1],attr.value)
                }
                let key=attr.value;
                this.update(node,key,attrName)
            }
        })
     
    }
    update(node,key,attrName){
        let updateFn=this[attrName+"Updater"];
        updateFn && updateFn.call(this,node,this.vm[key],key)

    }
    //处理v-text
    textUpdater(node,value,key){
        node.textContent=value;
        new Watcher(this.vm,key,(newval)=>{
            node.textContent=newval
        })
        node.addEventListener("input",()=>{
            this.vm[key]=node.textContent
        })
    }
    //处理v-model
    modelUpdater(node,value,key){
        node.value =value;
        new Watcher(this.vm,key,(newval)=>{
            node.value=newval
        })
        node.addEventListener("input",()=>{
            this.vm[key]=node.value
        })
    }
    htmlUpdater(node,value,key){
        //处理v-html
        node.innerHTML=value
        new Watcher(this.vm,key,(newVal)=>{
            node.innerHTML=newVal;
        })
    }
    bindlistnner(node,value,key){
        //处理v-on
       // node.addEventListener()
       let reg=/(.+)\((.+)\)/;
       let val=[]
       let newVal=null
       if(reg.test(key)){
          key=RegExp.$1.trim();
          val=RegExp.$2.trim().split(",");
          val.forEach((item,index)=>{
            val[index]=this.hasDate(item)
        })
       }
      
      console.log()
       node.addEventListener(value,()=>{
           console.log(...val)
            this.vm.$options.methods[key](...val)
            
       })
    }
    hasDate(val){
        //判断参数是否包含data数据
        return this.vm[val]
    }
    compileText(node){
        //编译文本节点  处理插值表达式
        let reg=/\{\{(.+)\}\}/
        let value=node.textContent;
        if(reg.test(value)){
            let key=RegExp.$1.trim();
            node.textContent=value.replace(reg,this.vm[key])
            new Watcher(this.vm,key,(newval)=>{
                node.textContent=newval
            })
        }
    }
    isDirective(attName){
        //判断元素属性是否指令
        return attName.startsWith("v-")
    }
    isTextNode(node){
        //判断是否是文本节点
        return node.nodeType===3
    }
    isElementNode(node){
        //判断节点是否是元素节点
        return node.nodeType===1
    }
}